/********************************************************
 ** Nombre: GestorCuentasDeAlumno.java                  *
 ** Version: 1.0.0                                      *
 ** Diagrama: GAPI v4.5.6                               *
 ** Autor: Alberto de Jesús Castro Becerra              *
 ** Creado: 16-mar-2013                                 *
 ** Modificado:                                         *
 ********************************************************/
package Servicios;

import DAO.DAOAlumno_PE;
import DAO.DAOAsignaturasAlumno;
import DAO.DAOAsignaturasOptativasAlumno;
import DAO.DAOCuentas;
import DAO.DAOInformacionAlumno;
import DAO.DAOInformacionPersonal;
import DAO.DAOProgramaEducativo;
import DAO.DAORelacionAlumnoProgramaEducativo;
import DAO.DAORespuestasEDD;
import DAO.DAORespuestasEHE;
import Dominio.Alumno;
import Dominio.CuentaSesion;
import Dominio.ProgramaEducativo;
import Dominio.Semestre;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Clase encargada de gestionar las operaciones a realizar sobre las cuentas de
 * alumno, tales como registrar cuentas de alumno, buscar cuentas de alumno,
 * modificación de contraseña de cuentas de alumno y eliminación de cuentas de
 * alumno.
 *
 * @author Alberto
 */
public class GestorDeCuentasDeAlumno extends HttpServlet {

    private final String ID_REGISTRO_CUENTA_ALUMNO = "registrarCuentaAlumno";
    private final String ID_BUSQUEDA_ALUMNO = "buscarAlumno";
    private final String ID_MODIFICACION_CONTRASENIA_ALUMNO = "modificarContraseniaAlumno";
    private final String ID_ELIMINACION_CUENTA_ALUMNO = "eliminarCuentaAlumno";
    private final String ID_MUESTRA_SEMESTRES = "muestraSemestres";
    private final int PRIVILEGIO_ALUMNO = 2;

    /**
     * Método encargado de gestionar la operación que se realizará sobre la
     * cuenta de alumno.
     *
     * @param request - petición
     * @param response - respuesta
     * @throws ServletException
     * @throws IOException M
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String peticion = request.getParameter("id");

        if (peticion != null) {

            if (peticion.equals(ID_REGISTRO_CUENTA_ALUMNO)) {
                registrarCuentaDeAlumno(request, response);
            } else if (peticion.equals(ID_BUSQUEDA_ALUMNO)) {
                buscarCuentaDeAlumno(request, response);
            } else if (peticion.equals(ID_MODIFICACION_CONTRASENIA_ALUMNO)) {
                modificarContraseniaDeAlumno(request, response);
            } else if (peticion.equals(ID_ELIMINACION_CUENTA_ALUMNO)) {
                eliminarCuentaDeAlumno(request, response);
            } else if (peticion.equals(ID_MUESTRA_SEMESTRES)) {
                mostrarSemestres(request, response);
            }

        } else {
            PrintWriter out = null;
            try {
                out = response.getWriter();
                out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
            } catch (IOException ex) {
                out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
            } finally {
                out.close();
            }
        }
    }

    /**
     * Método encargado de procesar peticiones get
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Método encargado de procesar peticiones post
     *
     * @param request - petición
     * @param response - respuesta
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Método encargado de registrar cuentas de alumno en la base de datos
     *
     * @param request - petición
     * @param response - respuesta
     */
    private void registrarCuentaDeAlumno(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            out = response.getWriter();

            String nombreDeUsuario = request.getParameter("nombre_usuario");
            String contrasenia = request.getParameter("contrasenia");
            String claveSemestreEnCadena = request.getParameter("semestre");
            String claveProgramaEducativoEnCadena = request.getParameter("programaEducativo");            
            String nombres = request.getParameter("nombres");
            String apellidoPaterno = request.getParameter("apellido_paterno");
            String apellidoMaterno = request.getParameter("apellido_materno");
            String edad = request.getParameter("edad");
            String direccion = request.getParameter("direccion");
            String telefono = request.getParameter("telefono");
            String sexo = request.getParameter("sexo");

            if (nombres != null && apellidoPaterno != null && apellidoMaterno != null && edad != null
                    && direccion != null && telefono != null && sexo != null && nombreDeUsuario != null && contrasenia != null
                    && claveSemestreEnCadena != null && claveProgramaEducativoEnCadena != null) {

                int claveSemestre = Integer.parseInt(claveSemestreEnCadena);
                int claveProgramaEducativo = Integer.parseInt(claveProgramaEducativoEnCadena);
                
                Alumno alumno = new Alumno();
                alumno.setNombres(nombres);
                alumno.setApellidoPaterno(apellidoPaterno);
                alumno.setApellidoMaterno(apellidoMaterno);
                alumno.setEdad(Integer.parseInt(edad));
                alumno.setDireccion(direccion);
                alumno.setTelefono(telefono);
                alumno.setSexo(sexo);

                CuentaSesion cuentaSesion = new CuentaSesion();
                cuentaSesion.setNombreUsuario(nombreDeUsuario);
                cuentaSesion.setContrasenia(contrasenia);

                alumno.setCuentaSesion(cuentaSesion);

                DAOCuentas daoCuentas = new DAOCuentas();

                if (!daoCuentas.existeCuenta(nombreDeUsuario)) {

                    DAOInformacionPersonal daoInformacionPersonal = new DAOInformacionPersonal();
                    int idInformacionPersonal = daoInformacionPersonal.registrarPersona(alumno);
                    
                    daoCuentas.registrarCuenta(cuentaSesion, PRIVILEGIO_ALUMNO, idInformacionPersonal);
                    daoCuentas.cerrarConexionACuentas();

                    DAOInformacionAlumno daoInformacionAlumno = new DAOInformacionAlumno();
                    daoInformacionAlumno.registrarInformacionPersonal(alumno);
                    int claveInformacionAlumno = daoInformacionAlumno.obtenerClaveInfoAlumno(nombreDeUsuario);
                    daoInformacionPersonal.cerrarConexionAPersonas();
                    
                    DAOAlumno_PE daoAlumno_pe = new DAOAlumno_PE();
                    daoAlumno_pe.registrarAlumnoAPE(claveInformacionAlumno, claveProgramaEducativo, claveSemestre);                    
                    daoInformacionPersonal.cerrarConexionAPersonas();

                    

                    out.println("El alumno se ha registrado exitosamente");
                } else {
                    out.println("El nombre de usuario ingresado no está disponible");
                }
            } else {
                out.println("Ocurrió un error al procesar la petición");
            }

        } catch (IOException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
            out.println("Ocurrió un error al procesar la petición");
        } finally {
            out.close();
        }
    }

    /**
     * Método encargado de buscar cuentas de alumno
     *
     * @param request - petición
     * @param response - respuesta
     */
    private void buscarCuentaDeAlumno(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            out = response.getWriter();
            String nombreDeUsuario = request.getParameter("nombre_usuario");
            if (nombreDeUsuario != null) {
                try {
                    DAOCuentas daoCuentas = new DAOCuentas();
                    ResultSet resultSetCuenta = daoCuentas.buscarInformacionPersonalDeCuenta(nombreDeUsuario, PRIVILEGIO_ALUMNO);

                    String contrasenia = "";

                    int contadorDeRegistros = 0;
                    while (resultSetCuenta.next()) {
                        contrasenia = resultSetCuenta.getString(2);

                        contadorDeRegistros++;
                    }

                    if (contadorDeRegistros == 0) {
                        out.println("No se encontr&oacute; el alumno");
                    }

                    daoCuentas.cerrarConexionACuentas();

                } catch (SQLException ex) {
                    Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
                    out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
                }

            } else {
                out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
            }
        } catch (IOException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
            out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
        } finally {
            out.close();
        }
    }

    /**
     * Método encargado de modificar contraseña de cuentas de alumno
     *
     * @param request - petición
     * @param response - repsuesta
     */
    private void modificarContraseniaDeAlumno(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            out = response.getWriter();
            String nombreDeUsuario = (String) request.getSession().getAttribute("nombreUsuario");
            String contraseniaActualRecibida = request.getParameter("contraseniaActual");
            String contraseniaNueva = request.getParameter("contraseniaNueva");

            if (nombreDeUsuario != null && contraseniaActualRecibida != null && contraseniaNueva != null) {

                DAOCuentas daoCuentas = new DAOCuentas();

                ResultSet resultSetCuentas = daoCuentas.buscarCuenta(nombreDeUsuario);
                String contraseniaActualEnBaseDeDatos = "";

                int contadorDeRegistros = 0;
                while (resultSetCuentas.next()) {
                    contraseniaActualEnBaseDeDatos = resultSetCuentas.getString(2);

                    contadorDeRegistros++;
                }

                if (contadorDeRegistros == 0) {
                    out.println("No se encontró el alumno");
                } else {
                    if (contraseniaActualEnBaseDeDatos.equals(contraseniaActualRecibida)) {
                        daoCuentas.actualizarContraseniaDeCuenta(nombreDeUsuario, contraseniaNueva);
                        out.println("Contraseña modificada exitosamente");
                    } else {
                        out.println("La contraseñaa actual no es la registrada en la base de datos");
                    }
                }
                daoCuentas.cerrarConexionACuentas();
            } else {
                out.println("Ocurrió un error al procesar la petición");
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
            out.println("Ocurrió un error al procesar la petición");
        } finally {
            out.close();
        }
    }

    /**
     * Método encargado de eliminar cuentas de alumno
     *
     * @param request - petición
     * @param response - respuesta
     */
    private void eliminarCuentaDeAlumno(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            out = response.getWriter();
            String nombreDeUsuario = (String) request.getSession().getAttribute("nombreUsuario");
            String contraseniaActualRecibida = request.getParameter("contraseniaActual");

            if (nombreDeUsuario != null && contraseniaActualRecibida != null) {

                DAOCuentas daoCuentas = new DAOCuentas();

                ResultSet resultSetCuentas = daoCuentas.buscarCuenta(nombreDeUsuario);
                String contraseniaActualEnBaseDeDatos = "";

                int contadorDeRegistros = 0;
                while (resultSetCuentas.next()) {
                    contraseniaActualEnBaseDeDatos = resultSetCuentas.getString(2);

                    contadorDeRegistros++;
                }

                if (contadorDeRegistros == 0) {
                    out.println("No se encontró el alumno");
                }
                else{
                    if(contraseniaActualEnBaseDeDatos.equals(contraseniaActualRecibida)){                                                //                                                                
                        
                        DAOInformacionAlumno daoInformacionAlumno = new DAOInformacionAlumno();
                        int claveInformacionAlumno = daoInformacionAlumno.obtenerClaveInfoAlumno(nombreDeUsuario);
                        daoInformacionAlumno.cerrarConexionADAOInformacionAlumno();
                        
                        DAORelacionAlumnoProgramaEducativo daoRelacionAlumnoPE = new DAORelacionAlumnoProgramaEducativo();
                        int claveRelacionAlumnoPE = daoRelacionAlumnoPE.obtenerClaveRelacionAlumnoPE(claveInformacionAlumno);
                        daoRelacionAlumnoPE.cerrarConexionARelacionAlumnoProgramaEducativo();
                        
                        DAOAsignaturasAlumno daoAsignaturasAlumno = new DAOAsignaturasAlumno();
                        daoAsignaturasAlumno.eliminarAsignaturasDelAlumno(claveRelacionAlumnoPE); 
                        daoAsignaturasAlumno.cerrarConexionAAsignaturaAlumno();
                        
                        DAOAsignaturasOptativasAlumno daoAsignaturasOptativasAlumno = new DAOAsignaturasOptativasAlumno();
                        daoAsignaturasOptativasAlumno.eliminarAsignaturasDelAlumno(claveRelacionAlumnoPE);
                        daoAsignaturasOptativasAlumno.cerrarConexionAAsignaturaOptativaAlumno();
                        
                        DAORespuestasEHE daoRespuestasEHE = new DAORespuestasEHE();
                        daoRespuestasEHE.eliminarRespuestasEHEDelAlumno(nombreDeUsuario);
                        daoRespuestasEHE.cerrarConexionARespuestasEHE();
                        
                        DAORespuestasEDD daoRespuestasEDD = new DAORespuestasEDD();
                        daoRespuestasEDD.eliminarRespuestasEDDDeAlumno(nombreDeUsuario);
                        daoRespuestasEDD.cerrarConexionARespuestasEHE();
                        
                        DAOAlumno_PE daoAlumnoPE = new DAOAlumno_PE();
                        daoAlumnoPE.eliminarRelacionAlumnoPE(claveInformacionAlumno);
                        daoAlumnoPE.cerrarConexionAReticulaAcademica();
                        
                        int claveInformacionPersonal = daoCuentas.buscarInformacionPersonal(nombreDeUsuario);                                                      
                        
                        daoCuentas.eliminarCuenta(nombreDeUsuario);  
                        
                        DAOInformacionPersonal daoInformacionPersonal = new DAOInformacionPersonal();
                        daoInformacionPersonal.eliminarInformacionPersonal(claveInformacionPersonal);
                        daoInformacionPersonal.cerrarConexionAPersonas();
                        
                        request.getSession().invalidate();
                        out.println("Cuenta eliminada exitosamente"); 
                    }
                    else{
                        out.println("La contraseña actual no es la registrada en la base de datos");
                    }
                }
                daoCuentas.cerrarConexionACuentas();
            } else {
                out.println("Ocurrió un error al procesar la petición");
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
            out.println("Ocurrió un error al procesar la peticón");
        } finally {
            out.close();
        }
    }

    /**
     * Método encargado de construir el combobox de selección del semestre de acuerdo con el programa educativo
     * indicado por el alumno durante la Configuración Académica del mismo.
     * @param request - petición
     * @param response - respuesta
     */
    private void mostrarSemestres(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            int clavePrograma = Integer.parseInt(request.getParameter("claveProg"));
            String noResp = "<td>Seleccione su semestre:</td><td><select name='semestre' id='semestre'><option value='-1'>Seleccione</option></select></td>";
            String iniCmb = "<td>Seleccione su semestre:</td><td><select name='semestre' id='semestre'><option value='-1'>Seleccione</option>";
            String finCmb = "</select></td>";
            String opciones = "";
            out = response.getWriter();
            if (clavePrograma == -1) {
                out.println(noResp);
            } else {
                DAOProgramaEducativo daope = new DAOProgramaEducativo();
                ProgramaEducativo p = daope.buscarPrograma(clavePrograma);
                ArrayList<Semestre> listaSemestres = p.getReticula().getListaDeSemestres();
                String aOp = "<option value='";
                String bOp = "'>";
                String cOp = "</option>";
                for (int i = 0; i < listaSemestres.size(); i++) {
                    int claveSemestre = listaSemestres.get(i).getClaveSemestre();
                    int numeroSemestre = listaSemestres.get(i).getNumeroDeSemestre();
                    
                    opciones += aOp + claveSemestre + bOp + "Semestre " + numeroSemestre + cOp;
                }
                out.println(iniCmb + opciones + finCmb);
            }
        } catch (IOException ex) {
            Logger.getLogger(GestorDeCuentasDeAlumno.class.getName()).log(Level.SEVERE, null, ex);
            out.println("Ocurri&oacute; un error al procesar la petici&oacute;n");
        } finally {
            out.close();
        }

    }        
}
